package com.jrx.anytxn.transaction.job.autoPayment.config;

import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.mapper.ext.ExtPrAutoPaymentTableMapper;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.transaction.config.AnytxnBatchProperties;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.AmLoanAccountInfo;
import com.jrx.anytxn.transaction.entity.BtAutoPaymentList;
import com.jrx.anytxn.transaction.job.autoPayment.step.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.transaction.PlatformTransactionManager;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 批扣第一次初始化
 *
 * @author : zhenghaopu
 * 2019/11/22
 */
@Configuration
@EnableConfigurationProperties(AnytxnBatchProperties.class)
public class AutoPaymentFirstInitConfiguration {

    Logger logger = LoggerFactory.getLogger(AutoPaymentFirstInitConfiguration.class);

    @Resource(name = "bizSqlSessionFactory")
    SqlSessionFactory sqlSessionFactory;

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    private AnytxnBatchProperties anytxnBatchProperties;

    @Autowired
    private IOrganizationTableService organizationTableService;
    @Autowired
    private AutoPaymentFirstInitStep1Processor autoPaymentFirstInitStep1Processor;

    @Autowired
    private AutoPaymentFirstInitStep2Processor autoPaymentFirstInitStep2Processor;
    @Autowired
    private AutoPaymentFirstInitWriter autoPaymentFirstInitWriter;
    @Autowired
    private AutoPaymentInitListener autoPaymentInitListener;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;
    @Resource
    private ExtPrAutoPaymentTableMapper extPrAutoPaymentTableMapper;

    @Bean
    public Job autoPaymentFirstInitJob(){
        return jobBuilderFactory.get("autoPaymentFirstInitJob")
                .listener(autoPaymentInitListener)//清空批次表
                .start(checkFirstInitStep()).on(ExitStatus.FAILED.getExitCode()).end()
                .from(checkFirstInitStep()).on("*").to(autoPaymentFirstInitStep1()).next(autoPaymentFirstInitStep2())
                .build()
                .build();
    }

    @Bean
    public Step checkFirstInitStep() {
        return stepBuilderFactory.get("checkFirstInitStep")
                .listener(checkFirstInitListener())
                .tasklet(checkFirstInitTasklet())
                .build();
    }

    private Tasklet checkFirstInitTasklet() {
        return (stepContribution, chunkContext) -> RepeatStatus.FINISHED;
    }

    @Bean
    public Step autoPaymentFirstInitStep1(){
        return stepBuilderFactory.get("autoPaymentFirstInitStep1")
                .<AmLoanAccountInfo, BtAutoPaymentList>chunk(anytxnBatchProperties.getAutoPaymentInitConfiguration().getChunkLimit())
                //表示一批处理100
                // 条记录，数据是逐条发送给processor处理的，处理100条记录后，统一返回给writer进行保存处理
                .reader(autoPaymentFirstInitStep1Reader())
                .processor(autoPaymentFirstInitStep1Processor)
                .writer(autoPaymentFirstInitWriter)
                .transactionManager(platformTransactionManager)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchProperties.getAutoPaymentInitConfiguration().getThrottleLimit())//多线程*/
                .build();
    }


    @Bean
    @StepScope
    public ItemReader<AmLoanAccountInfo> autoPaymentFirstInitStep1Reader() {
        //获取需要批扣的产品
        List<String> prAutoPaymentTables = extPrAutoPaymentTableMapper.selectProIdByAutoPaymentFlag(TransBizConstant.YES_FLAG);
        List<String> productIds = new ArrayList<>();
        for(String productIdString : prAutoPaymentTables){
            productIds.addAll(Arrays.asList(productIdString.split(",")));
        }
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
        Date businessDate = org.getNextProcessingDate();
        return new AutoPaymentFirstInitStep1Reader(businessDate,sqlSessionFactory,
                anytxnBatchProperties.getAutoPaymentInitConfiguration().getPageSize(),productIds);
    }

    @Bean
    public Step autoPaymentFirstInitStep2(){
        return stepBuilderFactory.get("autoPaymentFirstInitStep2")
                .<AmLoanAccountInfo, BtAutoPaymentList>chunk(anytxnBatchProperties.getAutoPaymentInitConfiguration().getChunkLimit())
                //表示一批处理100
                // 条记录，数据是逐条发送给processor处理的，处理100条记录后，统一返回给writer进行保存处理
                .reader(autoPaymentFirstInitStep2Reader())
                .processor(autoPaymentFirstInitStep2Processor)
                .writer(autoPaymentFirstInitWriter)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchProperties.getAutoPaymentInitConfiguration().getThrottleLimit())//多线程*/
                .build();
    }


    @Bean
    @StepScope
    public ItemReader<AmLoanAccountInfo> autoPaymentFirstInitStep2Reader() {
        //获取需要批扣的产品
        List<String> prAutoPaymentTables = extPrAutoPaymentTableMapper.selectProIdByAutoPaymentFlag(TransBizConstant.YES_FLAG);
        List<String> productIds = new ArrayList<>();
        for(String productIdString : prAutoPaymentTables){
            productIds.addAll(Arrays.asList(productIdString.split(",")));
        }
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
        Date businessDate = org.getNextProcessingDate();
        return new AutoPaymentFirstInitStep2Reader(businessDate,sqlSessionFactory,
                anytxnBatchProperties.getAutoPaymentInitConfiguration().getPageSize(),productIds);
    }

    @Bean
    public StepExecutionListener checkFirstInitListener(){
        return new SkipCheckingListener();
    }


    public class SkipCheckingListener extends StepExecutionListenerSupport {
        @Override
        public ExitStatus afterStep(StepExecution stepExecution) {
            List<String> prAutoPaymentTables = extPrAutoPaymentTableMapper.selectProIdByAutoPaymentFlag(TransBizConstant.YES_FLAG);
            if(CollectionUtils.isEmpty(prAutoPaymentTables)) {
                logger.info("没有");
                return ExitStatus.FAILED;
            } else {
                return ExitStatus.COMPLETED;
            }
        }

    }
}
